<?php

namespace app\unify\controller;

use app\BaseController;
use FFMpeg\Coordinate\TimeCode;
use FFMpeg\FFMpeg;
use Imagick;
use Intervention\Image\Drivers\Gd\Driver;
use Intervention\Image\ImageManager;
use think\annotation\route\Validate;
use think\App;
use think\db\Query;
use think\facade\Db;
use think\facade\Filesystem;
use think\Request;
use \app\unify\model\Source as SourceModel;
use app\unify\validate\Source as SourceValidate;


class Source extends BaseController
{
    /**
     * @Notes 资源列表
     * @Author EdwardCho
     * @Date 2024/1/3
     * @Time 23:51
     * @Interface index
     * @param \think\Request $r
     * @return \think\Paginator
     * @throws \think\db\exception\DbException
     */
    #[Validate(SourceValidate::class, scene: SourceValidate::INDEX)]
    public function index(Request $r)
    {
        $where = [];

        $keyword = $r->param('keyword');
        if ($keyword) {
            $where[] = ['name|desc', 'LIKE', "%{$keyword}%"];
        }

        $type = $r->param('type', 'all');
        if ($type != "all") {
            $where[] = ['type', '=', $type];
        }

        return SourceModel::where($where)->order('gmt_create DESC')->append(['platformName', 'creatorName'])->paginate($this->limit);

    }

    /**
     * @Notes 新增资源
     * @Author EdwardCho
     * @Date 2023/12/14
     * @Time 11:44
     * @Interface add
     */
    public function save(Request $r)
    {

        $file = $r->file('file');
        if (empty($file)) {
            throw new \Exception('请指定上传的文件');
        }

        $ext = strtolower($file->extension());
        $size = $file->getSize();
        $originalName = $file->getOriginalName();


        $ruleList = [
            [
                'name' => '图片',
                'type' => 'image',
                'size' => config('upload.image_size'),
                'ext' => explode(',', config('upload.image_ext'))
            ],
            [
                'name' => '视频',
                'type' => 'video',
                'size' => config('upload.video_ext'),
                'ext' => explode(',', config('upload.video_ext'))
            ],
            [
                'name' => '文件',
                'type' => 'file',
                'size' => config('upload.file_ext'),
                'ext' => explode(',', config('upload.file_ext'))
            ]
        ];

        //确认文件类型

        foreach ($ruleList as $rule) {
            if (in_array($ext, $rule['ext'])) {
                if ($size > $rule['size'] && $rule['size'] != 0) {
                    $unit = "KB";
                    if ($rule['size'] > 1000) {
                        $rule['size'] /= 1000;
                        $unit = "MB";
                    }
                    if ($rule['size'] > 1000) {
                        $rule['size'] /= 1000;
                        $unit = "GB";
                    }
                    throw new \Exception("上传失败，{$rule['name']}大小不超过{$rule['size']}{$unit}");
                }


                $saveName = Filesystem::disk('public')->putFile($rule['type'], $file, 'sha1');
                $temp = explode(".", $saveName);
                $temp[count($temp) - 2] .= "_thumb";
                $thumbSaveName = implode(".", $temp);

                $rootFullName = config('filesystem.disks.public.root') . DIRECTORY_SEPARATOR . $saveName;
                $thumbRootFullName = config('filesystem.disks.public.root') . DIRECTORY_SEPARATOR . $thumbSaveName;

                $url = \request()->domain(true) . config('filesystem.disks.public.url') . '/' . $saveName;
                $thumbUrl = \request()->domain(true) . config('filesystem.disks.public.url') . '/' . $thumbSaveName;

                $resolution = "";
                if ($rule['type'] == 'image') {
                    if(in_array(strtolower($ext), ['ico'])){
                        $thumbUrl = $url;
                    }else{
                        // 获取图片信息
                        $imageInfo = getimagesize($rootFullName);
                        $resolution = $imageInfo[0] . 'x' . $imageInfo[1];

                        $imageManager = new ImageManager(Driver::class);
                        $image = $imageManager->read($rootFullName);
                        $image->resize(width: 100, height: 100);
                        $image->toJpg()->save($thumbRootFullName);
                    }
                } else if ($rule['type'] == 'video') {
                    $ffmpeg = FFMpeg::create();
                    $video = $ffmpeg->open($rootFullName);
                    $videoFormat = $video->getStreams()->videos()->first();
                    $resolution = $videoFormat->get('width') . 'x' . $videoFormat->get('height');

                    // 获取视频的第一帧图片
                    $frame = $video->frame(TimeCode::fromSeconds(0));

                    $temp = explode(".", $thumbRootFullName);
                    $temp[count($temp) - 1] = 'jpg';
                    $thumbRootFullName = implode(".", $temp);
                    $frame->save($thumbRootFullName);

                    $imageManager = new ImageManager(Driver::class);
                    $image = $imageManager->read($thumbRootFullName);
                    $image->resize(width: 100, height: 100);
                    $image->toJpg()->save($thumbRootFullName);

                    $temp = explode(".", $thumbUrl);
                    $temp[count($temp) - 1] = 'jpg';
                    $thumbUrl = implode(".", $temp);
                }

                //保存文件
                SourceModel::create([
                    'platform' => SourceModel::PLATFORM_LOCAL,
                    'type' => $rule['type'],
                    'url' => $url,
                    'thumb_url' => $thumbUrl,
                    'size' => $size,
                    'resolution' => $resolution,
                    'ext' => $ext,
                    'desc' => '',
                    'name' => $originalName,
                    'creator' => \app\unify\model\User::id(),
                ]);

                return '操作成功';
            }
        }
        throw new \Exception("暂不支持上传{$ext}格式文件");
    }


    /**
     * @Notes 修改资源
     * @Author EdwardCho
     * @Date 2023/12/14
     * @Time 11:48
     * @Interface update
     * @param \think\Request $r
     * @param mixed $id
     */
    #[Validate(SourceValidate::class, scene: SourceValidate::UPDATE)]
    public function update(Request $r, int $id)
    {
        $source = SourceModel::findOrEmpty($id);
        if ($source->isEmpty()) {
            throw new \Exception('未找到该资源');
        }

        $params = $r->only(['desc']);

        $source->save($params);

        return '操作成功';
    }


    /**
     * @Notes 资源表单
     * @Author EdwardCho
     * @Date 2023/12/14
     * @Time 11:47
     * @Interface form
     */
    public function form()
    {
        $entity = [];
        return [
            'typeList' => SourceModel::TYPE_LIST,
            'platformList' => SourceModel::PLATFORM_LIST,
            'entity' => $entity,
        ];
    }

    /**
     * 删除资源
     *
     * @param array $ids
     * @return string
     */
    #[Validate(SourceValidate::class, scene: SourceValidate::DELETE)]
    public function delete(array $ids): string
    {
        Db::transaction(function () use ($ids) {
            SourceModel::destroy(function (Query $q) use ($ids) {
                $q->where([
                    [SourceModel::getPrimaryKey(), 'in', $ids]
                ]);
            });
        });

        return '删除成功';
    }


}